package user

import (
	"context"
	"fmt"
	"goHelpers/app/cache/user"
	"goHelpers/app/constant"
	"goHelpers/app/entity"
	myErr "goHelpers/app/error"
	errMsg "goHelpers/app/error/user"
	model "goHelpers/app/model/user"
	service "goHelpers/app/service/user"

	bootEntity "gitee.com/copylian/lian-go.git/entity"
	jwtHelper "gitee.com/copylian/lian-go.git/helper/jwt"
	pageHelper "gitee.com/copylian/lian-go.git/helper/page"
	stringsHelper "gitee.com/copylian/lian-go.git/helper/strings"
	timeHelper "gitee.com/copylian/lian-go.git/helper/time"
)

// userLogic 逻辑结构体
type userLogic struct {
	Ctx context.Context
}

// NewLogic 实例化结构体逻辑层
func NewLogic(ctx context.Context) *userLogic {
	return &userLogic{Ctx: ctx}
}

// Register 注册
func (l *userLogic) Register(req *entity.User) (affectedRows int64, rErr myErr.Error) {
	// 错误
	err := myErr.NewError("user")

	// 实例化服务层
	s := service.NewService(l.Ctx)

	// 验证数据
	userInfo := s.GetInfoByUserName(req.Username)
	if userInfo.Id > 0 {
		err.SetCodeMsg(errMsg.UserExists)
		return 0, err
	}

	// 实例化模型
	m := model.NewModel(l.Ctx)

	// 注册
	// 处理密码
	req.Salt = stringsHelper.GetRand(6)
	req.Password = stringsHelper.CreatePassword(req.Password, req.Salt)
	affectedRows = m.Register(req)

	// 返回
	return affectedRows, nil
}

// Login 登录
func (l *userLogic) Login(req *entity.User) (token string, rErr myErr.Error) {
	// 错误
	err := myErr.NewError("user")

	// 实例化服务层
	s := service.NewService(l.Ctx)

	// 查询数据
	userInfo := s.GetInfoByUserName(req.Username)
	if userInfo.Id == 0 {
		err.SetCodeMsg(errMsg.UserNoExists)
		return token, err
	}

	// 验证密码是否正确
	// 处理密码
	password := stringsHelper.CreatePassword(req.Password, userInfo.Salt)
	if userInfo.Password != password {
		err.SetCodeMsg(errMsg.PasswordErr)
		return token, err
	}

	// 生成jwt token
	token = jwtHelper.GenerateToken(bootEntity.ClaimData{Data: map[string]interface{}{
		"user_id": userInfo.Id,
	}}, &bootEntity.JwtConfig{JwtSecret: constant.JwtSecret, JwtTTL: constant.JwtTTL})

	// 返回
	return token, nil
}

// Info 获取信息
func (l *userLogic) Info(user_id uint32) (userInfo *entity.User) {
	// 实例化服务层
	s := service.NewService(l.Ctx)
	userInfo = s.GetInfoByUserId(user_id)

	// 处理时间
	if len(userInfo.CreateTime) > 0 {
		userInfo.CreateTime = timeHelper.RfcToLocalDatetime(userInfo.CreateTime, "")
	}
	if len(userInfo.UpdateTime) > 0 {
		userInfo.UpdateTime = timeHelper.RfcToLocalDatetime(userInfo.UpdateTime, "")
	}
	return
}

// List 获取列表
func (l *userLogic) List(req *entity.PageParams) (rdata *entity.UserList) {
	// 计算分页位移
	req.Page, req.Limit, req.Offset = pageHelper.InitCodion(req.Page, req.Limit)

	// 实例化模型
	m := model.NewModel(l.Ctx)

	// 获取列表
	userList, total := m.List(req)

	// 处理数据
	for k, v := range userList {
		// 处理时间
		if len(v.CreateTime) > 0 {
			userList[k].CreateTime = timeHelper.RfcToLocalDatetime(v.CreateTime, "")
		}
	}

	// 返回数据
	rdata = &entity.UserList{
		List: userList,
		Pagination: entity.Pagination{
			Page:     req.Page,
			Total:    total,
			LastPage: pageHelper.GetLastPage(total, req.Limit),
		},
	}
	return
}

// Redis redis操作
func (l *userLogic) Redis(user_id uint32) (affectedRows int64) {
	// 实例化缓存
	uc := user.NewCache(l.Ctx)

	// // 设置
	// err := uc.Set(1, &entity.UserInfo{
	// 	Id:         1,
	// 	Username:   "只袄早",
	// 	Sex:        1,
	// 	CreateTime: timeHelper.TimeToDate(time.Now().Unix(), ""),
	// })
	// fmt.Printf("err: %v\n", err)

	// // 获取
	// res2, err2 := uc.Get(1)
	// userInfo := entity.UserInfo{}
	// json.Unmarshal([]byte(res2), &userInfo)
	// fmt.Printf("userInfo: %#v\n", userInfo)
	// fmt.Printf("err2: %v\n", err2)

	// // 删除
	// err3 := uc.Del(1)
	// fmt.Printf("err3: %v\n", err3)

	// // 增加
	// inc, err4 := uc.IncrBy(1, 10)
	// fmt.Printf("err4: %v\n", err4)
	// fmt.Printf("inc: %v\n", inc)

	// list写入
	res5, err5 := uc.Lpush(user_id, "aaa")
	fmt.Printf("res5: %v\n", res5)
	fmt.Printf("err5: %v\n", err5)
	uc.Lpush(user_id, 111)

	return affectedRows
}
